package crmdna.client;

import static crmdna.common.OfyService.ofy;
import static crmdna.common.OfyService.ofyCrmDna;

import java.util.List;

import com.googlecode.objectify.Ref;

import crmdna.common.APIException;
import crmdna.common.APIResponse.Status;
import crmdna.user.UserEntity;

public class Client {
	private static ClientEntity create(String name, String displayName) {

		name = name.toLowerCase();
		// truncate name to 8 char
		if (name.length() > 8)
			name = name.substring(0, 8);

		ClientEntity clientEntity = ofyCrmDna().load().type(ClientEntity.class)
				.id(name).get();

		if (null != clientEntity)
			throw new APIException(Status.ERROR_RESOURCE_ALREADY_EXISTS,
					"There is already a client with name [" + name + "]");

		clientEntity = new ClientEntity();
		clientEntity.name = name;
		clientEntity.displayName = displayName;
		ofyCrmDna().save().entity(clientEntity).now();

		return clientEntity;
	}

	public static ClientEntity create(String name) {
		return create(name, name);
	}

	public static ClientEntity safeGet(String client) {
		if (null == client)
			throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST,
					"Client [" + client + "] does not exist");

		ClientEntity entity = ofyCrmDna().load().type(ClientEntity.class)
				.id(client).get();
		if (null == entity)
			throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST,
					"Client [" + client + "] not found");

		return entity;
	}

	public static ClientEntity get(String client) {
		if (null == client)
			throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST,
					"Client [" + client + "] does not exist");

		ClientEntity entity = ofyCrmDna().load().type(ClientEntity.class)
				.id(client).get();

		return entity;
	}

	public static List<ClientEntity> getAll() {
		List<ClientEntity> clients = ofyCrmDna().load()
				.type(ClientEntity.class).order("name").list();
		return clients;
	}

	public static ClientEntity updateDisplayName(String client,
			String newDisplayName) {

		ClientEntity clientEntity = ofyCrmDna().load().type(ClientEntity.class)
				.id(client).get();

		if (null == clientEntity)
			throw new APIException(Status.ERROR_RESOURCE_ALREADY_EXISTS,
					"Client [" + client + "] does not exist");

		clientEntity.displayName = newDisplayName;
		ofyCrmDna().save().entity(clientEntity).now();

		return clientEntity;
	}

	public static void ensureValidClient(String client) {
		safeGet(client);
	}

	static void addUser(String client, String email) {
		email = email.toLowerCase();

		ClientEntity clientEntity = safeGet(client);

		Ref<ClientEntity> clientRef = Ref.create(clientEntity);

		CrmDnaUserEntity crmdnaUserEntity = ofyCrmDna().load()
				.type(CrmDnaUserEntity.class).id(email).get();

		if (null == crmdnaUserEntity) {
			crmdnaUserEntity = new CrmDnaUserEntity();
			crmdnaUserEntity.email = email;
			crmdnaUserEntity.clients.add(clientRef);
		} else {
			crmdnaUserEntity.clients.add(clientRef);
		}

		ofyCrmDna().save().entity(crmdnaUserEntity);

		// add as a valid user in the client's namespace
		UserEntity userEntity = ofy(client).load().type(UserEntity.class)
				.id(email).get();

		if (null == userEntity) {
			userEntity = new UserEntity();
			userEntity.email = email;
			ofy(client).save().entity(userEntity);
		}
	}

	static void deleteUser(String client, String email) {
		email = email.toLowerCase();

		ClientEntity clientEntity = safeGet(client);

		Ref<ClientEntity> clientRef = Ref.create(clientEntity);

		CrmDnaUserEntity cmrdnaUserEntity = ofyCrmDna().load()
				.type(CrmDnaUserEntity.class).id(email).get();

		if (null != cmrdnaUserEntity) {
			boolean found = cmrdnaUserEntity.clients.remove(clientRef);
			if (found)
				ofyCrmDna().save().entity(cmrdnaUserEntity);

			// remove from client's namespace
			UserEntity userEntity = ofy(client).load().type(UserEntity.class)
					.id(email).get();

			if (null != userEntity) {
				ofy(client).delete().entity(userEntity).now();
			}
		}
	}

	static List<UserEntity> getAllUsers(String client) {
		List<UserEntity> list = ofy(client).load().type(UserEntity.class)
				.order("email").list();

		return list;
	}
}
